﻿using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using System.Web;

namespace lingopen.Application.Common
{
    public class AliyunHelper
    {
        public class BackendServer
        {
            public string ServerId { get; set; }
            public int Port { get; set; }
            public int Weight { get; set; }
        }

        private static string format = "json";
        private static string version = "2014-05-15";
        private static string accessKeyId = "LTAIxFF1JAJKHacj";
        private static string accessKeySecret = "70RlTJFteWZgdaxfzmUfuclAmVteTX";
        private static string signatureMethod = "HMAC-SHA1";
        private static string regionId = "cn-hangzhou";
        private static string signatureVersion = "1.0";

        private static string ecsVersion = "2014-05-26";

        #region ECS
        public static string DescribeInstanceStatus()
        {
            var version = ecsVersion;
            var timestamp = GetTimeStamp();
            var signatureNonce = GetNonce();
            var action = "DescribeInstanceStatus";
            var dic = new Dictionary<string, string>()
            {
                { "Format", "json" },
                { "Version", version },
                { "AccessKeyId", accessKeyId },
                { "SignatureMethod", signatureMethod },
                { "Timestamp", UrlEncode(timestamp) },
                { "SignatureVersion", signatureVersion },
                { "SignatureNonce", signatureNonce },
                { "Action", action },
                { "RegionId", regionId },
                { "PageSize", "50" }
            };
            var signature = CalcSignature(dic);
            var pubInfo = $"Format={format}&Version={version}&AccessKeyId={accessKeyId}"
                + $"&SignatureMethod={signatureMethod}&Timestamp={timestamp}&SignatureVersion={signatureVersion}&SignatureNonce={signatureNonce}&Signature={signature}";
            var url = $"https://ecs.aliyuncs.com/" + $"?" + pubInfo
                + $"&Action={action}&RegionId={regionId}&PageSize=50";
            WebClient wc = new WebClient();
            var s = wc.DownloadString(url);
            return s;
        }
        #endregion

        #region 负载平衡
        public static bool AddVServerGroupBackendServers(string vServerGroupId, List<BackendServer> servers)
        {
            var timestamp = GetTimeStamp();
            var signatureNonce = GetNonce();
            var action = "AddVServerGroupBackendServers";
            var backendServers = JArray.FromObject(servers.Select(o =>
                new Dictionary<string, string>() {
                    { "ServerId", o.ServerId },
                    { "Port", o.Port+"" },
                    { "Weight", o.Weight+"" }
                }).ToList()).ToString(Newtonsoft.Json.Formatting.None);
            var dic = new Dictionary<string, string>()
            {
                { "Format", "json" },
                { "Version", version },
                { "AccessKeyId", accessKeyId },
                { "SignatureMethod", signatureMethod },
                { "Timestamp", UrlEncode(timestamp) },
                { "SignatureVersion", signatureVersion },
                { "SignatureNonce", signatureNonce },
                { "Action", action },
                { "RegionId", regionId },
                { "VServerGroupId", vServerGroupId },
                { "BackendServers", UrlEncode(backendServers) }
            };
            var signature = CalcSignature(dic);
            var pubInfo = $"Format={format}&Version={version}&AccessKeyId={accessKeyId}"
                + $"&SignatureMethod={signatureMethod}&Timestamp={timestamp}&SignatureVersion={signatureVersion}&SignatureNonce={signatureNonce}&Signature={signature}";
            var url = $"https://slb.aliyuncs.com/" + $"?" + pubInfo
                + $"&Action={action}&RegionId={regionId}&VServerGroupId={vServerGroupId}&BackendServers={backendServers}";
            WebClient wc = new WebClient();
            var s = wc.DownloadString(url);
            return true;
        }
        public static bool RemoveVServerGroupBackendServers(string vServerGroupId, List<BackendServer> servers)
        {
            var timestamp = GetTimeStamp();
            var signatureNonce = GetNonce();
            var action = "RemoveVServerGroupBackendServers";
            var backendServers = JArray.FromObject(servers.Select(o =>
                new Dictionary<string, string>() {
                    { "ServerId", o.ServerId },
                    { "Port", o.Port+"" }
                }).ToList()).ToString(Newtonsoft.Json.Formatting.None);
            var dic = new Dictionary<string, string>()
            {
                { "Format", "json" },
                { "Version", version },
                { "AccessKeyId", accessKeyId },
                { "SignatureMethod", signatureMethod },
                { "Timestamp", UrlEncode(timestamp) },
                { "SignatureVersion", signatureVersion },
                { "SignatureNonce", signatureNonce },
                { "Action", action },
                { "RegionId", regionId },
                { "VServerGroupId", vServerGroupId },
                { "BackendServers", UrlEncode(backendServers) }
            };
            var signature = CalcSignature(dic);
            var pubInfo = $"Format={format}&Version={version}&AccessKeyId={accessKeyId}"
                + $"&SignatureMethod={signatureMethod}&Timestamp={timestamp}&SignatureVersion={signatureVersion}&SignatureNonce={signatureNonce}&Signature={signature}";
            var url = $"https://slb.aliyuncs.com/" + $"?" + pubInfo
                + $"&Action={action}&RegionId={regionId}&VServerGroupId={vServerGroupId}&BackendServers={backendServers}";
            WebClient wc = new WebClient();
            var s = wc.DownloadString(url);
            return true;
        }
        #endregion
        private static string GetNonce()
        {
            return Guid.NewGuid().ToString("N");
        }
        private static string GetTimeStamp()
        {
            return DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ssZ");
        }
        //将集合key以ascii码从小到大排序
        private static Dictionary<string, string> AsciiDictionary(Dictionary<string, string> sArray)
        {
            Dictionary<string, string> asciiDic = new Dictionary<string, string>();
            string[] arrKeys = sArray.Keys.ToArray();
            Array.Sort(arrKeys, string.CompareOrdinal);
            foreach (var key in arrKeys)
            {
                string value = sArray[key];
                asciiDic.Add(key, value);
            }
            return asciiDic;
        }
        private static string UrlEncode(string str)
        {
            StringBuilder builder = new StringBuilder();
            foreach (char c in str)
            {
                if (HttpUtility.UrlEncode(c.ToString()).Length > 1)
                {
                    builder.Append(HttpUtility.UrlEncode(c.ToString()).ToUpper());
                }
                else
                {
                    builder.Append(c);
                }
            }
            return builder.ToString();
        }
        private static string CalcSignature(Dictionary<string, string> dic)
        {
            var str = "GET&%2F&" + UrlEncode(String.Join("&", AsciiDictionary(dic).Select(o => o.Key + "=" + o.Value)));
            var key = accessKeySecret + "&";
            HMACSHA1 hmacsha1 = new HMACSHA1(Encoding.UTF8.GetBytes(key));
            byte[] rstRes = hmacsha1.ComputeHash(Encoding.UTF8.GetBytes(str));
            string strs = Convert.ToBase64String(rstRes);
            return UrlEncode(strs);
        }
    }
}
